/*
 * TDaneWej.java
 *
 * Created on 4 czerwiec 2007, 19:38
 *
 * Zamienia dane z lasera do formatu xyz.
 *
 * Format z lasera :
 *
 * Y
 * /\  -Z (w tyl)
 * |  /
 * | /
 * |/
 * ------> X (robot stoi wzdloz osi X)
 *
 */
package wej;

import gra.TVisualisation;
import ste.*;
import gra.TGlowneOkno;
import out.*;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.*;
import java.math.BigDecimal;
import javax.vecmath.*; //do grafiki
import java.awt.geom.*;

/**
 *
 * @author Michal
 */
public class TDaneWej extends TAbstBlock {

    public static final double MAX_VAL = 100d; //domyślna wartość tabeli odczytu danych
    
    private final static byte PLIK_LAS = 0; //rodzaj pliku 
    private final static byte PLIK_GAZ = 1; //rodzaj pliku 
    private final static byte PLIK_XYZ = 2; //rodzaj pliku 
    
    private final static double VER_STEP = 1; //co ile w pionie
    private final static double HOR_STEP = 1; //co ile w poziom
    private final static double MAX_DIST = 9d; //metry
    private final static int PION_MIN = 0;//82;//0; //min. kat w poziomie
    private final static int PION_MAX = 90;//83;//90;  //max kat w poziomie
    private final static boolean WIELE_SKA = false; //czy mozliwe wiele skanow dla 1 kata
    private final static String LASER = "laser";
    private final static String PTZ = "ptz";
    private final static String POSITION = "position";
    public final static int ILE_LASER = 181;//181; //ile pktow z lasera w 1. linii
    private final static String KOMENTARZ = "//"; //komentarz w oryginale
    private final static String SEPARATOR = " ";
    private TGlowneOkno fGloOkn; //g��wne okno do klepsydry
    private File theFile; //plik do odczytu
    private String[] theDesc = {
        "Odczyt w pionie [st.]",
        "Odczyt w poziomie [st.]",
        "Maks. odleglosc [m.]",
        "Min. kat w pionie [st.]",
        "Maks. kat w pionie [st.]",
        "Wiele skanow dla jednego kata" //checkBox
    };
    private double theVerStep,  theHorStep,  theMaxDist; //ustawienia poczatkowe.
    private double theMinPion,  theMaxPion; //ustawienia poczatk. (tylko laser)
    private JSpinner theVerSpi = new JSpinner(new SpinnerNumberModel(VER_STEP, 0, 100, 0.1));
    private JSpinner theHorSpi = new JSpinner(new SpinnerNumberModel(HOR_STEP, 0, 100, 0.1));
    private JSpinner theMaxDistSpi = new JSpinner(new SpinnerNumberModel(MAX_DIST, 0, 100, 0.1));
    private JSpinner thePionMinSpi = new JSpinner(new SpinnerNumberModel(PION_MIN, -100, 100, 0.1));
    private JSpinner thePionMaxSpi = new JSpinner(new SpinnerNumberModel(PION_MAX, 0, 100, 0.1));
    private JCheckBox theWieleSkaChB = new JCheckBox("", WIELE_SKA);//wiele skan�w dla jednego kata
    private JFileChooser theFileCh = new JFileChooser(System.getProperty("user.dir"));
    private boolean isLaserEnableF = true; //flaga, do blokowania odczytu wielu danych z lasera dla jednego k�ta
    private static int theMaxDistCnt = 0; //licznik ile poza zakresem
    private static double thePionAng = 0; //kat obrotu lasera w pionie [stopnie]
    private ArrayList<Point3d> fPtAL = new ArrayList<Point3d>(); //do grafiki
    private static Point2D theRobPos = new Point2D.Double();
    
    public TDaneWej() {
        theFileCh.setBackground(Color.BLUE);
    } //koniec konstruktora

    public void starter(IOut o) {
    } //metoda potrzebna tylko ze wzgl�du na dziedziczenie

    public void finish() {} //metoda potrzebna tylko ze wzgl.na dziedziczenie
    
    public void addGloOkn(TGlowneOkno tgo) {
        fGloOkn = tgo;
    } //koniec addGloOkn

    public void setNext(TAbstBlock aN) {
        theNext = aN;
    } //koniec setNext

    public String getTabTitle() {
        return "Dane wejsciowe";
    }//Laser/Gazebo > xyz"; }
    
    public JComponent getJComponent() {
        
        JPanel jp = new JPanel();
        jp.setBackground(Color.orange);

        //1. Dodanie przyciskow (laser i Gazebo)
        JPanel jpB = new JPanel(new GridLayout(2, 1, 10, 10)); //do przyciskow
        JButton lasB = new JButton("Wczytaj plik z lasera");
        lasB.setRolloverEnabled(true);
        lasB.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //new TReadFileThr(true).start();
                new TReadFileThr(PLIK_LAS).start();
            }
        });
        jpB.add(lasB);

        JButton gazB = new JButton("Wczytaj plik z Gazebo");
        gazB.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //new TReadFileThr(false).start();
                new TReadFileThr(PLIK_GAZ).start();
            }
        });
        jpB.add(gazB);

        JButton xyzB = new JButton("Wczytaj plik xyz");
        xyzB.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                new TReadFileThr(PLIK_XYZ).start();
            }
        });
        jpB.add(xyzB);
        //----
        jp.add(theFileCh);
        //====
        jp.add(jpB);
        //2. Dodanie ustawien poczatkowych
        jp.add(getSetP());

        //3. Dodanie danych do wizualizacji
        jp.add(getObjP());

        return jp;
    } //koniec getJComponent

    private JComponent getSetP() {//panel z ustawieniami poczatkowymi
        JPanel jp = new JPanel(new GridLayout(0, 2));
        Font font = new Font("System", Font.BOLD, 16);
        int _cnt = 0; //licznik pomocniczy

        //Odczyt w pionie
        jp.add(new JLabel(theDesc[_cnt++].concat(" : "), JLabel.RIGHT));
        theVerSpi.setFont(font);
        jp.add(theVerSpi);

        //Odczyt w poziomie
        jp.add(new JLabel(theDesc[_cnt++].concat(" : "), JLabel.RIGHT));
        theHorSpi.setFont(font);
        jp.add(theHorSpi);

        //Max odleglosc
        jp.add(new JLabel(theDesc[_cnt++].concat(" : "), JLabel.RIGHT));
        theMaxDistSpi.setFont(font);
        jp.add(theMaxDistSpi);

        //Min kat w pionie
        jp.add(new JLabel(theDesc[_cnt++].concat(" : "), JLabel.RIGHT));
        thePionMinSpi.setFont(font);
        jp.add(thePionMinSpi);

        //Max kat w pionie
        jp.add(new JLabel(theDesc[_cnt++].concat(" : "), JLabel.RIGHT));
        thePionMaxSpi.setFont(font);
        jp.add(thePionMaxSpi);

        //Czy mozliwe wiele odczytow dla jednego konta
        jp.add(new JLabel(theDesc[_cnt++].concat(" : "), JLabel.RIGHT));
        jp.add(theWieleSkaChB);

        jp.setBorder(BorderFactory.createTitledBorder("Ustawienia poczatkowe : "));
        return jp;
    } //koniec getSetP

    public void checkSettings() {//spr. i pobiera ustawienia poczatkowe
        try {
            theVerStep = Double.parseDouble(theVerSpi.getValue().toString());
            theHorStep = Double.parseDouble(theHorSpi.getValue().toString());
            theMaxDist = Double.parseDouble(theMaxDistSpi.getValue().toString());
            theMinPion = Double.parseDouble(thePionMinSpi.getValue().toString());
            theMaxPion = Double.parseDouble(thePionMaxSpi.getValue().toString());
        } catch (NumberFormatException err) { //chyba niepotrzebne (?)
            showErr("Bledne ustawienia poczatkowe : " + err +
                    "\nZostana przyjete ustawienia domyslne !");
            theVerStep = VER_STEP;
            theHorStep = HOR_STEP;
            theMaxDist = MAX_DIST;
            theMinPion = PION_MIN;
            theMaxPion = PION_MAX;
        } //koniec try-catch

        //Spr. ustawienia poczatkowe nastepnego modu�u
        if (theNext != null) {
            theNext.checkSettings();
        }
    } //koniec checkSettings

    public void clear() {
        if (fPtAL != null) {
            fPtAL.clear();
        }
        if (theNext != null)
            theNext.clear(); //wyzerowanie nastepnego modueu
    } //koniec clear

    //private void readFile(boolean isLaser) { //(true-laser, false-gazebo)
    private void readFile(byte aMode) { //(true-laser, false-gazebo)
        //1. Sprawdzam, czy ustawienia sa prawidlowe. Jezeli tak, to pobieram
        checkSettings();
        if (theMaxDistCnt > 0) {
            theMaxDistCnt = 0;
        } //zeruje licznik odrzuconych danych
        if (thePionAng != 0) {
            thePionAng = 0;
        }
        //2. Ewentualnie zeruje baze punktow (dla ka�dego modu�u
        clear();

        //1. Odczyt pliku
        //-- stary sposób
        /*
        JFileChooser lReadChF = new JFileChooser(System.getProperty("user.dir"));
        int res = lReadChF.showDialog(null, "Wybierz plik");
        if (res == 1) {
            return;
        } //cz. wcisnieto CANCEL
         */
        //===
        
        //3. Ustawiam kursor na klepsydre
        Cursor cur = new Cursor(Cursor.WAIT_CURSOR);
        fGloOkn.setCursor(cur);

        //theFile = lReadChF.getSelectedFile();
        theFile = theFileCh.getSelectedFile();
        TVisualisation.setSrcFile(theFile); //zapisanie nazwy pliku do grafiki

        //Odczytuje plik i zapamietuje wszystkie linie
        //if (readFile1(theFile, isLaser)) { //cz. udalo sie odczytac plik
        if (readFile1(theFile, aMode)) { //cz. udalo sie odczytac plik

            //Ustawiam kursor z powrotem
            cur = new Cursor(Cursor.DEFAULT_CURSOR);
            fGloOkn.setCursor(cur);

            JOptionPane.showMessageDialog(null,
                    "K O N I E C !\n" +
                    "Ilosc dobrych punktow: " + fPtAL.size() +
                    ",\nPoza zakresem: " + theMaxDistCnt + " punktow",
                    "Koniec", JOptionPane.INFORMATION_MESSAGE);
        } else {
            JOptionPane.showMessageDialog(null,
                    "Blad w odczycie pliku : " + theFile,
                    "Blad w odczycie pliku",
                    JOptionPane.WARNING_MESSAGE);
        }
    } //koniec readFile

    //private boolean readFile1(File aFile, boolean isLaser) {
    private boolean readFile1(File aFile, byte aMode) {
        boolean outFlag; //info, czy udalo sie odczytac plik
        try {
            //1. Zapisuje wszystko do ArrayList
            BufferedReader br = new BufferedReader(new FileReader(aFile));
            String line = null;
            ArrayList<String> lLineAL = new ArrayList<String>();
            while ((line = br.readLine()) != null) {
                if (!line.startsWith(KOMENTARZ) && line.length() > 0) { //komentarz
                    //Spr. czy jest komentarz w linii
                    if (line.indexOf(KOMENTARZ) > 0)//czyli jest komentarz
                        line = line.substring(0, line.indexOf(KOMENTARZ));
                    lLineAL.add(line.trim());
                } //koniec if
            } //koniec while

            br.close(); //zamkniecie strumienia;
            if (lLineAL.size() > 1) { //cz. jest przynajmniej jedna linia
                String[] linT = new String[lLineAL.size()];
                linT = lLineAL.toArray(linT);

                //Analizuje linia po linii
                if (linT.length > 0)
                    fGloOkn.getProBar().setMaximum(linT.length - 1);
                
                if (aMode!=PLIK_XYZ) {
                    
                    for (int i = 0; i < linT.length; i++) {
                        //Zapisanie w pasku postepu
                        fGloOkn.getProBar().setValue(i);

                        //1. Kasuje podwojne spacje
                        while (linT[i].indexOf(SEPARATOR.concat(SEPARATOR)) != -1) {
                            linT[i] = linT[i].replaceAll(SEPARATOR.concat(SEPARATOR), SEPARATOR);
                        }
                        ///ArrayList<TXyz> lXyz2DAL = isLaser ? getElkaALFromLine(linT[i]) : getGazALFromLine(linT[i].split(SEPARATOR), i * theVerStep);
                        //---
                        //ArrayList<TXyz> lXyz2DAL=null;
                        ArrayList<Point3d> lXyz2DAL=null;
                        switch (aMode) {
                            case(PLIK_LAS) : lXyz2DAL = getElkaALFromLine(linT[i]); break;
                            case(PLIK_GAZ) : lXyz2DAL = getGazALFromLine(linT[i].split(SEPARATOR), i * theVerStep); break;
                        } //koniec switch
                        //===

                        if (lXyz2DAL.size() == 0) {//ignoruje te linie (np. ## Player version 1.6.5 )
                            continue;
                        }

                        //Tworze pkty do grafiki i wysylam do nastepnego modudulu
                        //for (TXyz xyz : lXyz2DAL)
                        for (Point3d xyz : lXyz2DAL)
                            addPoint(xyz.getX(), xyz.getY(), xyz.getZ());

                        //Wywolanie modulu Basi
                        if (theNext != null)
                            theNext.starter(new TOut1_2(lXyz2DAL));
                    } //koniec for i                   
                    theNext.finish();
                } else { //cz. odczyt xyz (ca�y plik a nie po linii)
                    xyzFromFile(linT);
                } //koniec if-else
                outFlag = true;
            } else {
                showErr("Za malo danych");
                outFlag = false;
            } //koniec if-else
        } catch (FileNotFoundException err) {
            showErr("ERR_01: " + err);
            outFlag = false;
        } catch (IOException err) {
            showErr("ERR_02: " + err);
            outFlag = false;
        } //koniec try-catch
        return outFlag;
    } //koniec readFile1

    /************************************/
    /*  Sekcja z obroka danych z lasera */
    /************************************/
    //private ArrayList<TXyz> getElkaALFromLine(String aLine) {
    //    ArrayList<TXyz> lXyzAL = new ArrayList<TXyz>();
    private ArrayList<Point3d> getElkaALFromLine(String aLine) {
        ArrayList<Point3d> lXyzAL = new ArrayList<Point3d>();

        String[] lStrT = aLine.split(SEPARATOR);
        if (lStrT.length < 4) { //cz. za malo danych w wszu
            showErr("blad w wierszu: " + aLine);
            return lXyzAL;
        } //koniec if
        double lAlfaAng = 0, lAlfaStep = 0;
        double[] lLasT = new double[ILE_LASER];
        try {
            if (lStrT[3].trim().equals(LASER)) {
                //1. Blokuje odczyt wielu skanow dla jednego kata w pionie
                if (!theWieleSkaChB.isSelected()) { //cz. musze sprawdzic, czy moge czytac
                        if (isLaserEnableF) isLaserEnableF=false;
                        else return lXyzAL; //cz. dla tego kata w pionie juz byl odczyt
                } //koniec if
                
                if (lStrT.length != 372) {
                    showErr("Zla ilosc danych w wierszu: " + ", jest: " + lStrT.length);
                    return lXyzAL;
                } //koniec if
                lAlfaAng = Double.parseDouble(lStrT[6]); //radiany
                lAlfaStep = Double.parseDouble(lStrT[8]); //radiany
                int _cnt = 10; //pierwsze 10 liczb nie ma znaczenia
                for (int i = 0; i < lLasT.length; i++) {
                    lLasT[i] = Double.parseDouble(lStrT[_cnt]);
                    _cnt += 2;
                    //Obsluguje tylko gdy jest dobry kat w poziomie
                    if (theMinPion <= thePionAng && thePionAng <= theMaxPion && lLasT[i] <= theMaxDist) { //Spr. czy nie jest poza zakresem

                        //lXyzAL.add(new TXyz(getXYZ(lLasT[i],Math.toDegrees(lAlfaAng), thePionAng, true)));
                        lXyzAL.add(new Point3d(getXYZ(lLasT[i],Math.toDegrees(lAlfaAng), thePionAng, true)));
                        lAlfaAng += lAlfaStep; //krok bierze z pliku
                    } else { //cz. poza zakresem
                        theMaxDistCnt++;  //cz.ile odrzucono
                    } //koniec if-else
                } //koniec for
            } else if (lStrT[3].trim().equals(PTZ)) { //czyli zmiana kata w pionie
                //Ewentualnie odblokowuje mozliwosc czytania z lasera (bo nowy kat)
                if (!theWieleSkaChB.isSelected() && !isLaserEnableF)
                    isLaserEnableF=true; //umozliwaiam odczyt
                thePionAng = Double.parseDouble(lStrT[7]);
                
            } else if (lStrT[3].trim().equals(POSITION)) { //czyli zmiana kata w pionie
//Point2D oldPos = new Point2D.Double(theRobPos.getX(), theRobPos.getY());
                theRobPos.setLocation(Double.parseDouble(lStrT[6]), 
                                        Double.parseDouble(lStrT[7]));
//if (oldPos.distance(theRobPos) > 0) //cz. położenie się zmieniło
//    System.out.println ("theRobPos: " + theRobPos);
                
            } //koniec if - else
        } catch (NumberFormatException err) {
            showErr("Blad w konwersji typow w linii: " + aLine);
            return lXyzAL;
        } catch (ArrayIndexOutOfBoundsException err) {
            showErr("Blad w ilosci zmiennch w linii: " + aLine);
            return lXyzAL;
        } //koniec try-catch

        return lXyzAL;
    } //koniec getElkaALFromLine
    //=== koniec sekcji z obrobka danych z lasera
    /************************************/
    /*  Sekcja z obroka danych z Gazebo */
    /************************************/
    //private ArrayList<TXyz> getGazALFromLine(String[] aLinT, double aVerStep) {//czytam 1linie danych z Gazebo
    //    ArrayList<TXyz> lXyzAL = new ArrayList<TXyz>();
    private ArrayList<Point3d> getGazALFromLine(String[] aLinT, double aVerStep) {//czytam 1linie danych z Gazebo
        ArrayList<Point3d> lXyzAL = new ArrayList<Point3d>();

        //1. Zamieniam String na double
        double[] lVarT = new double[aLinT.length];
        for (int i = 0; i < lVarT.length; i++) {
            try {
                lVarT[i] = Double.parseDouble(aLinT[i].replace(',', '.').trim());
            } catch (NumberFormatException err) {
                showErr("Blad w konwersji typu");
                return lXyzAL;
            } //koniec try-catch
        } //koniec for

        for (int i = 0; i < lVarT.length; i++) { //caly plik
            if (lVarT[i] <= theMaxDist) { //Spr. czy nie jest poza zakresem
                // Dodaje pkt do listy z pktami
                lXyzAL.add(new Point3d(getXYZ(lVarT[i], theHorStep * i, aVerStep, false)));
                //lXyzAL.add(new TXyz(getXYZ(lVarT[i], theHorStep * i, aVerStep, false)));
            } else { //cz. za daleko
                theMaxDistCnt++; //zliczam ile poza zakresem
            }  //koniec if-else
        } //koniec for i
        return lXyzAL;
    } //koniec getGazALFromLine
    //=== koniec sekcji z obrobka danych z Gazebo
    
    // Obs�uga xyz 
    private void xyzFromFile(String[] aLinT) { //inaczej niz LASER i GAZEBO !!
        System.out.println ("linii jest aLinT.l: " + aLinT.length);

        //Zamieniam String na double
        String[] _linST;
        double[] xT = new double[ILE_LASER];//aLinT.length];
        double[] yT = new double[ILE_LASER];//aLinT.length];
        double[] zT = new double[ILE_LASER];//aLinT.length];
        Arrays.fill(xT,MAX_VAL);
        Arrays.fill(yT,MAX_VAL);//Double.MAX_VALUE);
        Arrays.fill(zT,MAX_VAL);//Double.MAX_VALUE);

        //Zamieniam String[] na 3 tabele double[]
        for (int i=0; i<aLinT.length; i++) {

            if (i%10000 == 0) 
                System.out.println ("#" + i + "/" + aLinT.length);
                
            //Kasuje podwojne spacje            
            while (aLinT[i].indexOf("  ")!=-1) aLinT[i] = aLinT[i].replace("  ", " ");
            
            _linST = aLinT[i].split(" ");
            
            try { 
                double x = Double.parseDouble(_linST[0].trim());
                double z = Double.parseDouble(_linST[1].trim());
                double y = Double.parseDouble(_linST[2].trim());

                //Obliczam pod jakim katem jest pkt i w zaleznosci od tego wrzucam do odpowiedniej komorki
                int ind=(int)(Math.toDegrees(Math.atan2(y, x)+Math.PI/2)+0.5);
                if((ind<0)||(ind>ILE_LASER)) {
                    System.out.println(ind+" blad kat poza przedzialem 0-180, ind: " + ind);
                    ind=0;
                    continue;
                } //koniec if
                
                if ((0<=ind) && (ind<xT.length)) {
                    xT[ind]=x;
                    yT[ind]=y;
                    zT[ind]=z;
                } //koniec if

                //Jeżeli odczytał do końca, to wysylam do nastepnego modulu
                if (ind==ILE_LASER-1 && xT[0]!=MAX_VAL){//Double.MAX_VALUE) {
                    //System.out.println("wysylam do nastepnego modulu");
                    ArrayList<Point3d> lXyz2DAL= new ArrayList<Point3d>();
                    for (int j=0; j<xT.length; j++) {
                        //System.out.println ("dodaję pkt xT[" + j + "]: " + xT[j] + ", y: " + yT[j] + ", z: " + zT[j]);
                        lXyz2DAL.add(new Point3d(xT[j], yT[j], zT[j]));
                    }
                    //System.out.println ("lXyz2DAL.s: " + lXyz2DAL.size());
                    //Tworze pkty do grafiki i wysylam do nastepnego modulu
            
                    for (Point3d xyz : lXyz2DAL)
                        addPoint(xyz.getX(), xyz.getY(), xyz.getZ());

                    fGloOkn.getProBar().setValue(i+1);//*ILE_LASER);
                    //Wywolanie do następnego modulu
                    if (theNext != null)
                        theNext.starter(new TOut1_2(lXyz2DAL));
                    
                    //Przygotowuje od nowa tablicę do zapisu
                    lXyz2DAL.clear();
                    Arrays.fill(xT,MAX_VAL);//Double.MAX_VALUE);
                    Arrays.fill(yT,MAX_VAL);//Double.MAX_VALUE);
                    Arrays.fill(zT,MAX_VAL);//Double.MAX_VALUE);
                } //koniec if

            } catch (NumberFormatException err) {
                JOptionPane.showMessageDialog(null,
                    "Blad w linii: " + i + ": --|" + aLinT[i] + "|--",
                    "Blad", JOptionPane.ERROR_MESSAGE);
                return;
            } //koniec try-catch
        } //koniec for
        
        theNext.finish();
    } //koniec xyzFromFile
    
    /*********************/
    /*  Sekcja z grafika */
    /*********************/
    public void addPoint(double aX, double aY, double aH) {
        fPtAL.add(new Point3d(aX, aY, aH));
    } //koniec addPoint

    public void showGraphic() {
        //--- test trojkatow
       /*
        Point3d[] _p3T = new Point3d[3];
        _p3T[0] = new Point3d(0, 0, 0);
        _p3T[1] = new Point3d(1, 0, 0);
        _p3T[2] = new Point3d(0, 1, 0);
        TVisualisation _lVis = new TVisualisation(); //do grafiki
        _lVis.addTriangleT(_p3T);
        Point3d[] _p3Ta = new Point3d[3];
        _p3Ta[0] = new Point3d(1, 0, 0);
        _p3Ta[1] = new Point3d(0, 1, 0);
        _p3Ta[2] = new Point3d(1, 1, 0);
        _lVis.addTriangleT(_p3Ta);
        Point3d[] _p3Tb = new Point3d[3];
        _p3Tb[0] = new Point3d(1, 0, 0);
        _p3Tb[1] = new Point3d(0, 1, 0);
        _p3Tb[2] = new Point3d(0, 0, 1);
        _lVis.addTriangleT(_p3Tb);
        _lVis.display();
        if (4<5) return;
         */
        //=== koniec testu tr�jk�t�w

        if (fPtAL.size() == 0) {
            return;
        } //gdy nie odczytano pliku
        Point3d[] p3T = new Point3d[fPtAL.size()];
        p3T = fPtAL.toArray(p3T);
        TVisualisation lVis = new TVisualisation(); //do grafiki
        lVis.addPtT(p3T);
        //Dodaj� kolejne ustawienia do pliku z raportem
/*        int _cnt = 0; //licznik pomocniczy
        
        lVis.addMes(theDesc[_cnt++], String.valueOf(round(theVerStep)));
        lVis.addMes(theDesc[_cnt++], String.valueOf(round(theHorStep)));
        lVis.addMes(theDesc[_cnt++], String.valueOf(round(theMaxDist)));
        lVis.addMes(theDesc[_cnt++], String.valueOf(round(theMinPion)));
        lVis.addMes(theDesc[_cnt++], String.valueOf(round(theMaxPion)));
 */       
        lVis.display(); //wy�wietlenie grafiki
    } //koniec showGraphic

    //=== koniec sekcji z grafika
    
    private static double[] getXYZ(double aR, double aPoziom, double aPion,
            boolean isLaserF) {
        double[] lOutT = new double[3]; //x, y, z
        double lPionRad = Math.toRadians(aPion);
        double lPoziomRad = Math.toRadians(aPoziom);
        lOutT[0] = round(isLaserF ? //x
                aR * Math.cos(lPionRad) * Math.cos(lPoziomRad) : //laser
                aR * Math.cos(lPionRad) * Math.sin(lPoziomRad)); //gazebo
        lOutT[1] = round(isLaserF ? //y
                aR * Math.sin(lPoziomRad) : //laser
                aR * Math.cos(lPoziomRad)); //gazebo
        lOutT[2] = round(isLaserF ? //h
                aR * Math.sin(lPionRad) * Math.cos(lPoziomRad) : //laser
                aR * Math.sin(lPionRad) * Math.sin(lPoziomRad));//gazebo
        
        //---
        //Uwzględniam położenie robota
        lOutT[0] += theRobPos.getX();
        lOutT[1] += theRobPos.getY();
        //===
        
        return lOutT;
    } //koniec getXYZ

    
    //Metody pomocnicze
    private static double round(double aVal) {
        BigDecimal bD = new BigDecimal(aVal);
        return bD.setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
    } //koniec round

    public int getMaxDist() {
        return (int) theMaxDist;
    }

    /********** Klasy wewnetrzne ***********/
    class TReadFileThr extends Thread {

        //private boolean theFlag;
        private byte theMode;

        TReadFileThr(byte aMode) {
            theMode = aMode;
        }
        /*
        TReadFileThr(boolean aFlag) {
            theFlag = aFlag;
        }
        */
        public void run() {
            //readFile(theFlag);
            readFile(theMode);
        } //koniec run
    } //koniec TReadFileThr
} //koniec klasy TDaneWej

